Skip to content

Check for _CountingAttr subclasses#1544

Open
LecrisUT wants to merge 1 commit intopython-attrs:mainfrom
LecrisUT:feat/allow_field_extension
Open

Check for _CountingAttr subclasses#1544
LecrisUT wants to merge 1 commit intopython-attrs:mainfrom
LecrisUT:feat/allow_field_extension

Conversation

@LecrisUT
Copy link
Copy Markdown
Contributor

Summary

The main purpose for this is to allow custom fields to extend the field decorators. This does technically enable that by subclassing the private class and adding the appropriate methods as in #1543.

I do not believe this is the best approach for handling #1543, it's just the quickest way to unblock it. The class should probably become something more public. If there are other ideas happy to explore them.

Pull Request Check List

  • I acknowledge this project's AI policy.
  • This pull requests is not from my main branch.
  • There's tests for all new and changed code.
  • Changes or additions to public APIs are reflected in our type stubs (files ending in .pyi).
    • ...and used in the stub test file typing-examples/baseline.py or, if necessary, typing-examples/mypy.py.
    • If they've been added to attr/__init__.pyi, they've also been re-imported in attrs/__init__.pyi.
  • The documentation has been updated.
    • New functions/classes have to be added to docs/api.rst by hand.
    • Changes to the signatures of @attr.s() and @attrs.define() have to be added by hand too.
    • Changed/added classes/methods/functions have appropriate versionadded, versionchanged, or deprecated directives.
      The next version is the second number in the current release + 1.
      The first number represents the current year.
      So if the current version on PyPI is 26.2.0, the next version is gonna be 26.3.0.
      If the next version is the first in the new year, it'll be 27.1.0.
    • Documentation in .rst and .md files is written using semantic newlines.
  • Changes have news fragments in changelog.d.

@hynek
Copy link
Copy Markdown
Member

hynek commented Apr 16, 2026

While I'm always super open to expand our… expandability… this needs more meat for the motivation. Like concrete examples that it enables – which could go straight into, probably, expanding.md?

In other words it seems a bit speculative rn in whether it actually achieves what you need/want in the second/third step. So I would like to see some proof (and docs) to show that.

@LecrisUT
Copy link
Copy Markdown
Contributor Author

Luckily I did make a test repo of my experimentations 😉 https://github.com/lecrisut/attrs-playground

@hynek
Copy link
Copy Markdown
Member

hynek commented May 10, 2026

Luckily I did make a test repo of my experimentations 😉 https://github.com/lecrisut/attrs-playground

does any of the examples use this? because the readme just says it's not supported. :)

as said if this helps you with something concrete I'm open to it. long-term we should get rid of _CountingAttr, since it comes with a bunch of surprising behavior. Unfortunately, there's probably a non-trivial amount of software depending on it it, tho. So I wouldn't want to block you with that.

@LecrisUT
Copy link
Copy Markdown
Contributor Author

does any of the examples use this? because the readme just says it's not supported. :)

Yeah, the readme is more intended for my colleagues. You can try out the example with and without the patch to see the difference. It is required, otherwise it would not detect the field 1 as a attrs.field , instead it treats it as an annotation and the metadata is gone.

long-term we should get rid of _CountingAttr, since it comes with a bunch of surprising behavior.

Right now it is only this idea that would depend on it, so there is no immediate rush. If there are ideas of what can take its place, then I'm all up for pivoting the design.

At the core of this I think the issue is that _CountingAttr has double-duty to guarantee the ordering of the attributes and to create the entry-point for the field decorators. The former could be dropped for sure, but the latter would still have to be around in one way or another. How about making a specific subclass to contain the latter to keep it "safe" for users to subclass from, and find a way to decouple these and drop the need for the former.

Footnotes

  1. https://github.com/LecrisUT/attrs-playground/blob/c95acef82de6d04c5b7e4be000a3623b4a658486/container.py#L68

@hynek
Copy link
Copy Markdown
Member

hynek commented May 10, 2026

No, I do not really have any ideas. I just want to get rid of the counting that we needed before Python 3.6. I'm mostly saying that I'm not married to anything about _CountingAttr.

I guess your subclassing idea makes sense; the q is just what the new class should do except being public?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants